#ifndef DAVPROPFIND_H
#define DAVPROPFIND_H


#include "base_modul.h"
#include "../qxml.h"
#include "basedav.h"
#include "networkdav.h"

///////class Qxml;
///////class NetworkDav;

class DavPROPFIND : public QObject, public Base_Modul
{
    Q_OBJECT
//
public: 
    DavPROPFIND( NetworkDav * db , const QString path )
{
    loopnummer = -1;
    dirlevel = -1;
    numerazione = 0;
    fnumerazione = 2000;

    pathregister = path;
    actualurl = db->Resolvpath(path);
    
    
    
    
    db = db;
    dummypath = db->DummiRoot();
    
    
    //////////qDebug() << "#### PROPFIND REQUEST--.  ->" << actualurl;
    davinfo = new QHttp();
    davinfo->setHost(db->Host(),db->Port());
    davinfo->setUser(db->User(),db->Pass());
    
    qt_unlink(REQUESTSTREAM); 
    ///////////qt_unlink(GETSTSTREAM); 
    
    if (!DavXmlBase()) {
    emit WarningMsg(tr("Unable to write on file %1").arg(REQUESTSTREAM));
    return;
    } else {
        
    QDateTime now = QDateTime::currentDateTime();
    tmpfilexml = QString( "%1%2_%3.xml" ).arg( WORK_CACHEDIR ).arg(QTime_Null()).arg(now.toString("zzz"));    
    BeamUpFile = new QFile(REQUESTSTREAM);  /* send comand file */
    BeamUpFile->open(QIODevice::ReadOnly);
    BeamLogFile = new QFile(tmpfilexml);     /* responder file info */
    BeamLogFile->open(QIODevice::ReadWrite);
    QHttpRequestHeader header("PROPFIND", actualurl ,1,1);   /* header */
    header.setValue("Host", db->Host());
    header.setValue("Depth","1");
    header.setValue("User-Agent", WEBAGENTNAME );
    header.setValue("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
    header.setValue("Accept-Language", "it,de-de;q=0.8,it-it;q=0.6,en-us;q=0.4,en;q=0.2");
    header.setValue("Connection", "keep-alive");
    header.setValue("Content-Type", "text/xml; charset=\"utf-8\"" );
    david = davinfo->request(header,BeamUpFile,BeamLogFile);
    connect(davinfo, SIGNAL(requestFinished(int, bool)), this, SLOT(Wake_Finish(int, bool)));
  
    }
}
void  SetPosition( int position )
{
  loopnummer =   position;
}
void  SetFormat( int format , int level )
{
  workonformat = format;
  dirlevel = level;
}
protected:
 bool DavXmlBase()
{
    QDomDocument davbaseinit;
    QDomProcessingInstruction header = davbaseinit.createProcessingInstruction( "xml",QString("version=\"1.0\" encoding=\"utf-8\"" ));
    
    davbaseinit.appendChild( header );
    QDomElement root = davbaseinit.createElement("D:propfind");
    root.setAttribute ("xmlns:D","DAV:");
    QDomElement propname = davbaseinit.createElement("D:allprop");
    root.appendChild(propname);
    davbaseinit.appendChild( root );
    fwriteutf8(REQUESTSTREAM,davbaseinit.toString());
    return is_file(REQUESTSTREAM);
}

 void DavReadProcess()
{
  QString errorStr, obname, inhalt, lister;
  int errorLine, errorColumn, position;
    
  BeamLogFile->close();
  BeamUpFile->close();
  davinfo->close();
    
    
    Copy_To(tmpfilexml,LASTACTIONB);
    
    XmlFile = new QFile(tmpfilexml);
    if(!XmlFile->open(QIODevice::ReadOnly)) {
        BeamLogFile->remove();
      emit WarningMsg(tr("Unable to read File").arg(XmlFile->fileName()));
      return;
     } 
     
     
     
     
     if (!doc.isNull()) {
     doc.~QDomDocument();
     } else {
     QDomDocument nedoc("");
     doc = nedoc;
     }
     
     if (!doc.setContent(XmlFile,false, &errorStr, &errorLine, &errorColumn)) {
       XmlFile->remove();
       BeamLogFile->remove();
      emit WarningMsg(tr("Error on dir list xml file: %1\nError %2\nLine %3\nColumn %4\nProcess url %5")
         .arg(XmlFile->fileName())
         .arg(errorStr)
         .arg(errorLine)
         .arg(errorColumn)
         .arg(actualurl));
         
         
      return;
     } 
    
     QDomElement root = doc.documentElement();
     
     
        QDomDocument qdavxml("WebDavDirList");
        QDomProcessingInstruction header = qdavxml.createProcessingInstruction( "xml",QString("version=\"1.0\" encoding=\"utf-8\"" ));
        qdavxml.appendChild( header );
        QDomElement droot = qdavxml.createElement("davdir");
        droot.setAttribute ("fromtime",QTime_Null());
        qdavxml.appendChild( droot );
     
       /////////////////////qDebug() << "####### root tag name  -> " << root.tagName(); 
     ///////qDebug() << "####### db->DummiRoot()  -> " << db->DummiRoot();
     
     
     RegiDir.clear();
     RegiFile.clear();
     
    QDomElement listdir = root.firstChildElement("D:response");
        while (!listdir.isNull()) {
            numerazione++;
            fnumerazione++;
            
            
            ///////qDebug() << "####### listdir tag name  -> " << listdir.tagName();
            
            
           QString itemname = listdir.firstChildElement("D:href").text();
           const QString realname = itemname;
            itemname = itemname.replace(dummypath,"/");
            
            ////////QUrl parturl(itemname);
           //////// QByteArray sx = parturl.toEncoded();
            ///////////itemname = sx.data();
            
            
              QDomElement propstat = listdir.firstChildElement("D:propstat");
              QDomElement prop = propstat.firstChildElement("D:prop");
           QString mime = prop.firstChildElement("D:getcontenttype").text();
           QString createdtime = prop.firstChildElement("lp1:creationdate").text();
           QString lastmodtime = prop.firstChildElement("lp1:getlastmodified").text();
           QString uniqueid = prop.firstChildElement("lp1:getetag").text();
                   uniqueid = uniqueid.replace("\"","");
           
           
            QString bite = prop.firstChildElement("lp1:getcontentlength").text();
            
            
            
           QString status = propstat.firstChildElement("D:status").text();
            
          ///////////////////qDebug() << "####### itemname -> " << itemname; 
           //////////qDebug() << "####### mime -> " << mime; 
           //////////qDebug() << "####### createdtime -> " << createdtime; 
           //////////qDebug() << "####### lastmodtime -> " << lastmodtime; 
           //////////qDebug() << "####### status -> " << status; 
            
             if (itemname.endsWith("/")) {
             QDomElement ddir = qdavxml.createElement("ddir");
                 ddir.setAttribute ("load",QTime_Null());
                 ddir.setAttribute ("name",itemname);
                 ddir.setAttribute ("lastmod",MailTimeString(lastmodtime));
                 ddir.setAttribute ("create",DavTimeStringCreated(createdtime));
                 ddir.setAttribute ("id",uniqueid);
                 ddir.setAttribute ("mime","dir");
                 ddir.setAttribute ("status",status);
                 ddir.setAttribute ("byte",0);
                 droot.appendChild( ddir );
                 
                       if (!RegiDir.contains(itemname)) {
                            RegiDir.append(itemname);
                       }
                 
                 
             } else {
             QDomElement dfile = qdavxml.createElement("dfile");
                 dfile.setAttribute ("load",QTime_Null());
                 dfile.setAttribute ("name",itemname);
                 dfile.setAttribute ("lastmod",MailTimeString(lastmodtime));
                 dfile.setAttribute ("create",DavTimeStringCreated(createdtime));
                 dfile.setAttribute ("id",uniqueid);
                 dfile.setAttribute ("mime",mime);
                 dfile.setAttribute ("status",status);
                 dfile.setAttribute ("byte",BiteorMega(direct_int(bite)));
                 droot.appendChild( dfile );
                          if (!RegiFile.contains(itemname)) {
                            RegiFile.append(itemname);
                          }
                 
             }
        listdir = listdir.nextSiblingElement("D:response");
        }
        
       XmlFile->remove();
       BeamLogFile->remove();
        
        
        
        /////////////////qDebug() << "####### xml -> " << qdavxml.toString(); 
        
        ///////////////emit WarningMsg(tr("Error on url: %1\nErrorMsg %2\nHeader Status code %3").arg(actualurl).arg(davinfo->errorString()).arg(statuscode)); 
        /////////return;
        
        if ( workonformat == INFODIRLISTFORMAT) {
            emit InfoDavList(RegiDir,RegiFile,dirlevel);
          return;  
        }
        
        if (loopnummer == 0 or loopnummer > 0) {
               int next = loopnummer + 1;
               emit LoopSubdir(qdavxml,pathregister,next); 
               return;
               } else {
               emit MDavInfoXmlItem(qdavxml,pathregister);
               return;       
         }
}
private:
  QString pathinfofile;
  QHttp *davinfo;
  QString tmpfilexml;
  //////NetworkDav *db;
  int dirlevel;
  QDomDocument doc;
  int david;
  int workonformat;
  int loopnummer;
  int numerazione;
  QSettings setter;
  int fnumerazione;
  QFile *BeamUpFile;
  QFile *BeamLogFile;
  QFile *XmlFile;
  QStringList RegiDir;
  QStringList RegiFile;
  QString actualurl;
  QString pathregister;
  QString xmlinfo;
  QString dummypath;
  QString DisplayName;
  int statuscode;
signals:
  void WarningMsg( QString e );
  void MDavInfoXmlItem( QDomDocument domi , QString path );
  void LoopSubdir( QDomDocument domi , QString path , int next ); 
  void Statusloop( int re , int to );
  void InfoDavList( QStringList ddir , QStringList ddile , int level );
public slots:
 void DavWake( bool error )
{
   
}
void  Wake_Finish( int requestId, bool error )
{
   if (requestId != david ) {
     return;
   }
    QHttpResponseHeader lastheader = davinfo->lastResponse();
    int statusbecome = lastheader.statusCode();
    if (error) {
    
     BeamLogFile->remove();
     BeamUpFile->remove();
     davinfo->close();
     emit WarningMsg(tr("Error on url: %1\nErrorMsg %2").arg(actualurl).arg(davinfo->errorString()));
    return;
    } 
    //////////qDebug() << "#### HEADER STATUS CODE  ->" << statusbecome; 
    if (statusbecome == 207) {
    DavReadProcess();
    return;
    } else {
     emit WarningMsg(tr("Error on url: %1\nErrorMsg %2\nHeader Status code %3").arg(actualurl).arg(davinfo->errorString()).arg(statusbecome)); 
        BeamLogFile->remove();
        BeamUpFile->remove();
        davinfo->close();
    }
}


void RegisterBackHeader(const QHttpResponseHeader &responseHeader )
{
   statuscode = responseHeader.statusCode();  
      
}

void  SendStatus( int Read, int total )
{
    emit Statusloop(Read,total);
}

};






//
#endif // DAVPROPFIND_H

